﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;



using Kitware.VTK;



namespace HAVTKPack
{



    public class HydrolicPlaneBarrierGeometry : Geometry
    {


        #region 构造函数


        public HydrolicPlaneBarrierGeometry(HydrolicGrid hg, List<int[,]> effectiveCellSign, List<PlaneBarrierData > barrierCellIJK)
        {

            this._hg = hg;
            this._effectiveSign = effectiveCellSign;
            this._barrierCellIJK = barrierCellIJK;

            if (this._barrierCellIJK ==null )
            {
                this._barrierCellIJK = new List<PlaneBarrierData>();
                
            }


            //伪代码  供测试使用
            //if (this._barrierCellIJK.Count <= 0)
            //{

            //    PlaneBarrierData planeBarrier1 = new PlaneBarrierData();

            //    planeBarrier1.Layer = 1;

            //    planeBarrier1.IROW1 = 1;
            //    planeBarrier1.ICOL1 = 1;

            //    planeBarrier1.IROW2 = 1;
            //    planeBarrier1.ICOL2 = 2;

            //    _barrierCellIJK.Add(planeBarrier1);

            //    //PlaneBarrierData planeBarrier2 = new PlaneBarrierData();

            //    //planeBarrier2.Layer = 1;
            //    //planeBarrier2.IROW1 = 1;
            //    //planeBarrier2.ICOL1 = 1;
            //    //planeBarrier2.IROW2 = 2;
            //    //planeBarrier2.ICOL2 = 2;

            //    //_barrierCellIJK.Add(planeBarrier1);

            //}
        
        
        }


        #endregion


        #region 字段属性

        HydrolicGrid _hg;
        /// <summary>
        /// 不规则网格数据源
        /// </summary>
        public HydrolicGrid Hg
        {
            get { return _hg; }
            set
            {

                _hg = value;
                this.OnHydrollicGridChanged();
            }
        }


        List<int[,]> _effectiveSign;
        /// <summary>
        /// 单元的有效性标记数组
        /// </summary>
        public  List<int[,]> EffectiveSign
        {
            get { return _effectiveSign; }
            set
            {

                _effectiveSign = value;
                this.OnEffectiveSignChanged();

            }
        }



        List<PlaneBarrierData> _barrierCellIJK;

        public List<PlaneBarrierData> BarrierCellIJK
        {
            get { return _barrierCellIJK; }

            set { 
                
                
                _barrierCellIJK = value;

                this.OnBarrierCellIJKChanged();
            }
        }




        //Vector scaleVector = new Vector(1, 1, 1);

        //public Vector ScaleVector
        //{
        //    get { return scaleVector; }
        //    set {
                
        //        scaleVector = value;

        //        this.OnScaleVectorChanged();
        //    }
        //}



        #endregion

        #region vtk流水线的对象

        vtkUnstructuredGrid unGrid;

        vtkQuad quad;

        vtkTransformFilter _transFormFilter;



        #endregion

        public override void Render()
        {

            unGrid = vtkUnstructuredGrid.New();

          
            quad = vtkQuad.New();
           


            this.GetPointsAndCellArray();

            if (this.GeometryTransform == null)
            {
                this.GeometryTransform = vtkTransform.New();
            }

            this.GeometryTransform.Identity();
            if (this.ParentNode !=null )
            {
                this.GeometryTransform.Scale(this.ParentNode.Scale.X, this.ParentNode.Scale.Y, this.ParentNode.Scale.Z);
            }
    

            _transFormFilter = vtkTransformFilter.New();
            _transFormFilter.SetTransform(this.GeometryTransform);
            _transFormFilter.SetInput(unGrid);


         
            this._outPutData = this._transFormFilter.GetOutput();



            //throw new NotImplementedException();
        }


        public override void StopRender()
        {
            if (this._transFormFilter != null)
            {
                this._transFormFilter.Dispose();
            }
            if (this.GeometryTransform  != null)
            {
                this.GeometryTransform.Dispose();
            }
            if (this.quad  != null)
            {
                this.quad.Dispose();
            }
            if (this.unGrid != null)
            {
                this.unGrid.Dispose();
            }




            //throw new NotImplementedException();
        }





        #region  共有方法

     


        #endregion


        #region 属性改变方法

        private void OnHydrollicGridChanged()
        {
            if (this._hg == null)
            {
                return;
            }

         
            this.GetPointsAndCellArray();

        }

        private void OnEffectiveSignChanged()
        {
            if (this.EffectiveSign == null)
            {
                return;
            }


         
            this.GetPointsAndCellArray();

        }

        private void OnBarrierCellIJKChanged()
        {
            if (this._barrierCellIJK  == null)
            {
                return;
            }

          
            this.GetPointsAndCellArray();

        }

        //private void OnScaleVectorChanged()
        //{


        //    this.GetPointsAndCellArray();
        
        
        //}

        #endregion


        #region 内部方法

        private void GetPointsAndCellArray()
        {
            if (this.unGrid == null)
            {
                return;
            }
        
            //_hg为外边框点信息

            int nLayer = this._hg.NLayers;
            int nCol = this._hg.NCols;
            int nRow = this._hg.NRows;
            int nPts = nLayer * nCol * nRow;

            int nPoints = 0;
            int nCells = 0;

            for (int layer = 0; layer < this._effectiveSign .Count ; layer++)
            {
                for (int row = 0; row < this._effectiveSign [layer ].GetLength (0); row++)
                {
                    for (int col = 0; col < this._effectiveSign [layer ].GetLength (1); col++)
                    {
                        if (this._effectiveSign [layer ][row,col ]!=0)
                        {
                            nCells = nCells + 1;
                        }
                    }
                }
            }



            int rowIndex1 = 0;
            int colIndex1=0;
            int rowIndex2 = 0;
            int colIndex2=0;
            int layerIndex = 0;

            if (this._barrierCellIJK ==null )
            {
                _barrierCellIJK = new List<PlaneBarrierData>();
            }
            for (int i = 0; i < this._barrierCellIJK .Count ; i++)
            {
                rowIndex1 = this._barrierCellIJK[i].IROW1 - 1;
                colIndex1 = this._barrierCellIJK[i].ICOL1 - 1;

                rowIndex2 = this._barrierCellIJK[i].IROW2 - 1;
                colIndex2 = this._barrierCellIJK[i].ICOL2 - 1;

                layerIndex = this._barrierCellIJK[i].Layer - 1;

                if (this._effectiveSign [layerIndex ][rowIndex1 ,colIndex1 ]!=0 && this._effectiveSign [layerIndex ][rowIndex2 ,colIndex2 ]!=0)
                {
                    nPoints = nPoints + 1;
                    
                }

            }


            if (nCells <= 0||nPoints <=0)
            {
                vtkDoubleArray array2 = vtkDoubleArray.New();
                array2.SetNumberOfComponents(3);
                array2.SetNumberOfTuples(0);//点的个数？？

                vtkPoints pts2 = vtkPoints.New();
                pts2.SetData(array2);

                vtkCellArray cellArray2 = vtkCellArray.New();
                cellArray2.SetNumberOfCells(0);

                vtkQuad quad2 = vtkQuad.New();

                unGrid.SetPoints(pts2);
                unGrid.SetCells(quad2.GetCellType(), cellArray2);

                unGrid.Modified();

                return;

            }

         

            vtkQuad aQuad = vtkQuad.New();




            vtkDoubleArray array = vtkDoubleArray.New();
            array.SetNumberOfComponents(3);
            array.SetNumberOfTuples(nPts);


            double X = 0;
            double Y = 0;
            double Z = 0;

            int m = 0;

            for (int k = 0; k < nLayer; k++)
            {
                for (int i = 0; i < nRow; i++)
                {

                    for (int j = 0; j < nCol; j++)
                    {

                        X = this._hg.Coords[i, j, k].X ;
                        Y = this._hg.Coords[i, j, k].Y ;
                        Z = this._hg.Coords[i, j, k].Z ;


                        array.SetTuple3(m, X, Y, Z);

                        m++;

                    }

                }

            }

            vtkPoints pts = vtkPoints.New();
            pts.SetData(array);



            vtkCellArray cellArray= vtkCellArray .New ();
            vtkQuad quadCell = null;


            for (int i = 0; i < this._barrierCellIJK.Count; i++)
            {
                rowIndex1 = this._barrierCellIJK[i].IROW1 - 1;
                colIndex1 = this._barrierCellIJK[i].ICOL1 - 1;

                rowIndex2 = this._barrierCellIJK[i].IROW2 - 1;
                colIndex2 = this._barrierCellIJK[i].ICOL2 - 1;

                layerIndex = this._barrierCellIJK[i].Layer - 1;


                if (this._effectiveSign[layerIndex][rowIndex1, colIndex1] != 0 && this._effectiveSign[layerIndex][rowIndex2, colIndex2] != 0)
                {


                    quadCell = vtkQuad.New();

                    int index0 = 0;
                    int index1 = 0;
                    int index2 = 0;
                    int index3 = 0;


                    if (rowIndex1 == rowIndex2)//同row不同col相邻的两个单元格
                    {
                        if (colIndex1 < colIndex2)
                        {

                            //0,1,2,3   对应   2,1,5,6
                            //hex.GetPointIds().SetId(2, (k + 1) * nRow * nCol + i * nCol + j + 1);
                            //hex.GetPointIds().SetId(1, (k + 1) * nRow * nCol + (i + 1) * nCol + j + 1);

                            //hex.GetPointIds().SetId(5, k * nRow * nCol + (i + 1) * nCol + j + 1);
                            //hex.GetPointIds().SetId(6, k * nRow * nCol + i * nCol + j + 1);


                            index0 = (layerIndex + 1) * nRow * nCol + rowIndex1 * nCol + colIndex1 + 1;
                            index1 = (layerIndex + 1) * nRow * nCol + (rowIndex1 + 1) * nCol + colIndex1 + 1;

                            index2 = layerIndex * nRow * nCol + (rowIndex1 + 1) * nCol + colIndex1 + 1;
                            index3 = layerIndex * nRow * nCol + rowIndex1 * nCol + colIndex1 + 1;



                            quadCell.GetPointIds().SetId(0, (layerIndex + 1) * nRow  * nCol + rowIndex1  * nCol + colIndex1 + 1);
                            quadCell.GetPointIds().SetId(1, (layerIndex + 1) * nRow * nCol + (rowIndex1+1) * nCol + colIndex1 + 1);

                            quadCell.GetPointIds().SetId(2, layerIndex * nRow * nCol + (rowIndex1 + 1) * nCol  + colIndex1 + 1);
                            quadCell.GetPointIds().SetId(3, layerIndex * nRow * nCol  + rowIndex1  * nCol  + colIndex1 + 1);




                            //quadCell.GetPointIds().SetId(0, 122);
                            //quadCell.GetPointIds().SetId(1, 133);

                            //quadCell.GetPointIds().SetId(2, 12);
                            //quadCell.GetPointIds().SetId(3, 1);




                        }
                        else if (colIndex2 < colIndex1)
                        {


                            quadCell.GetPointIds().SetId(0, (layerIndex + 1) * nRow * nCol + rowIndex1 * nCol + colIndex2 + 1);
                            quadCell.GetPointIds().SetId(1, (layerIndex + 1) * nRow * nCol + (rowIndex1 + 1) * nCol + colIndex2 + 1);

                            quadCell.GetPointIds().SetId(2, layerIndex * nRow * nCol + (rowIndex1 + 1) * nCol + colIndex2 + 1);
                            quadCell.GetPointIds().SetId(3, layerIndex * nRow * nCol + rowIndex1 * nCol + colIndex2 + 1);

                        }
                        else
                        {

                        }

                    }
                    else
                    {
                        //不同row同col相邻的两个单元格

                        if (rowIndex1 < rowIndex2)
                        {
                            //0,1,2,3   对应   0,1,5,4
                            //hex.GetPointIds().SetId(0, (k + 1) * nRow * nCol + (i + 1) * nCol + j);
                            //hex.GetPointIds().SetId(1, (k + 1) * nRow * nCol + (i + 1) * nCol + j + 1);

                            //hex.GetPointIds().SetId(5, k * nRow * nCol + (i + 1) * nCol + j + 1);
                            //hex.GetPointIds().SetId(4, k * nRow * nCol + (i + 1) * nCol + j);





                            quadCell.GetPointIds().SetId(0, (layerIndex + 1) * nRow * nCol + (rowIndex1 + 1) * nCol + colIndex1 );
                            quadCell.GetPointIds().SetId(1, (layerIndex + 1) * nRow  * nCol  + (rowIndex1 + 1) * nCol  + colIndex1 + 1);

                            quadCell.GetPointIds().SetId(2, layerIndex * nRow * nCol + (rowIndex1 + 1) * nCol + colIndex1 + 1);
                            quadCell.GetPointIds().SetId(3, layerIndex * nRow * nCol + (rowIndex1 + 1) * nCol + colIndex1);



                            //quadCell.GetPointIds().SetId(0, 132);
                            //quadCell.GetPointIds().SetId(1, 133);

                            //quadCell.GetPointIds().SetId(2, 12);
                            //quadCell.GetPointIds().SetId(3, 11);


                        }
                        else if (rowIndex2 < rowIndex1)
                        {
                            quadCell.GetPointIds().SetId(0, (layerIndex + 1) * nRow * nCol + (rowIndex2 + 1) * nCol + colIndex1);
                            quadCell.GetPointIds().SetId(1, (layerIndex + 1) * nRow * nCol + (rowIndex2 + 1) * nCol + colIndex1 + 1);

                            quadCell.GetPointIds().SetId(2, layerIndex * nRow * nCol + (rowIndex2 + 1) * nCol + colIndex1 + 1);
                            quadCell.GetPointIds().SetId(3, layerIndex * nRow * nCol + (rowIndex2 + 1) * nCol + colIndex1);
                        }
                        else
                        {

                        }

                    }


                    //hex.GetPointIds().SetId(0, (k + 1) * nRow * nCol + (i + 1) * nCol + j);
                    //hex.GetPointIds().SetId(1, (k + 1) * nRow * nCol + (i + 1) * nCol + j + 1);
                    //hex.GetPointIds().SetId(2, (k + 1) * nRow * nCol + i * nCol + j + 1);
                    //hex.GetPointIds().SetId(3, (k + 1) * nRow * nCol + i * nCol + j);

                    //hex.GetPointIds().SetId(4, k * nRow * nCol + (i + 1) * nCol + j);
                    //hex.GetPointIds().SetId(5, k * nRow * nCol + (i + 1) * nCol + j + 1);
                    //hex.GetPointIds().SetId(6, k * nRow * nCol + i * nCol + j + 1);
                    //hex.GetPointIds().SetId(7, k * nRow * nCol + i * nCol + j);



                    cellArray.InsertNextCell(quadCell);


                    quad.Initialize();




                }


            }
      
            unGrid.SetPoints(pts);

            unGrid.SetCells(quad.GetCellType(), cellArray);
      
            this.unGrid.Modified();

        
        
        }

        //private void UpdateTransformScale()
        //{
        //    缩放功能由其 Node 更改Scale属性设置

        //    if (this.GeometryTransform != null)
        //    {
        //        this.GeometryTransform.Identity();
        //        this.GeometryTransform.Scale(this.scaleVector.X, this.scaleVector.Y, this.scaleVector.Z);

        //    }
        
        //}

        #endregion













    }




}
